<template>
    <div class="dashboard-editor-container">
        <div class="main-header">
            <el-card class="box-card" shadow="never">
                <el-row class="btn-bottom">
                    <el-col :span="16">
                        <el-button type="primary" @click="addHost(1)">新增扫描任务</el-button>
                        <el-button type="primary" @click="getData()">刷新</el-button>
                    </el-col>
                </el-row>
                <el-dialog :title="this.Action === 1 ? '新增扫描任务' : '修改扫描任务'" top="5vh" :visible.sync="centerDialogVisible"
                    v-el-drag-dialog width="800px" @close='closeDialog' :close-on-press-escape=false
                    :close-on-click-modal=false>
                    <el-form :model="ipForm" ref="ipForm" :rules="IPRule" label-width="140px">
                        <el-row :gutter="24">
                            <el-col :sm="24" :md="24" :lg="24">
                                <el-form-item label="任务名称：" prop="Name">
                                    <el-input size="small" maxlength='40' type="text" v-model="ipForm.Name"></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row :gutter="24">
                            <el-col :sm="24" :md="24" :lg="24">
                                <el-form-item label="执行方式：" prop="ExecType">
                                    <el-radio v-model="ipForm.ExecType" :label="1">立即执行</el-radio>
                                    <el-radio v-model="ipForm.ExecType" :label="2">定期执行</el-radio>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row :gutter="24" v-if="ipForm.ExecType === 2">
                            <el-col :sm="24" :md="24" :lg="24">
                                <el-form-item label="扫描开始时间：" prop="LoopScan.StartTime">
                                    <el-date-picker v-model="ipForm.LoopScan.StartTime" type="datetime"
                                        value-format="timestamp" :default-value="new Date()"
                                        placeholder="选择日期时间"></el-date-picker>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row :gutter="24" v-if="ipForm.ExecType === 2">
                            <el-col :sm="24" :md="24" :lg="24">
                                <el-form-item label="扫描间隔：" prop="LoopScan.Interval">
                                    <el-input size="small" maxlength='40'
                                        v-model.number="ipForm.LoopScan.Interval"><template
                                            slot="append">时</template></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row :gutter="24">
                            <el-col :sm="24" :md="24" :lg="24">
                                <el-form-item label="扫描目标：" prop="TargetType">
                                    <el-radio-group v-model="ipForm.TargetType" @change="snmpChange">
                                        <el-radio :label="1" style="width:85px;">自定义</el-radio>
                                        <!-- <el-radio :label="2">指定IP组</el-radio> -->
                                        <el-radio :label="3">SNMP V1 / V2</el-radio>
                                        <el-radio :label="4">SNMP V3</el-radio>
                                    </el-radio-group>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row :gutter="24" v-show="ipForm.TargetType === 1">
                            <el-col :sm="24" :md="24" :lg="24">
                                <el-form-item label="极速扫描：" prop="QuickScan">
                                    <el-radio v-model="ipForm.QuickScan" :label="0">关闭</el-radio>
                                    <el-radio v-model="ipForm.QuickScan" :label="1">开启</el-radio>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row :gutter="24">
                            <el-col :sm="24" :md="24" :lg="24" v-if="ipForm.TargetType === 1">
                                <el-form-item label="" prop="TargetIpSegment">
                                    <el-input type="textarea" :rows="8" placeholder="请输入IP/IP段/IP范围，一行一个， 
例：192.168.1.1/24
192.168.1.100-200
192.168.1.200" size="small" v-model="ipForm.TargetIpSegment" style="width:100%"></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row :gutter="24">
                            <el-col :sm="24" :md="24" :lg="24" v-if="ipForm.TargetType === 2">
                                <el-form-item label="" prop="TargetDeviceGroupID">
                                    <el-cascader v-model="ipForm.TargetDeviceGroupID" placeholder="请选择" :options="nodeData"
                                        :show-all-levels="false"
                                        :props="{ label: 'Name', value: 'ID', children: 'Children', expandTrigger: 'click', multiple: true, emitPath: false }"
                                        style="width:100%">
                                    </el-cascader>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row :gutter="24">
                            <el-col :sm="24" :md="24" :lg="24" v-if="ipForm.TargetType === 3">
                                <el-form-item label="交换机地址：" prop="TargetSnmpScanV2.ServerIP">
                                    <el-input oninput="value=value.replace(/[^0-9.]/g,'')" size="small" maxlength='40'
                                        v-model="ipForm.TargetSnmpScanV2.ServerIP"></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row :gutter="24">
                            <el-col :sm="24" :md="24" :lg="24" v-if="ipForm.TargetType === 3">
                                <el-form-item label="交换机snmp端口：" prop="TargetSnmpScanV2.Port">
                                    <el-input @input="validatePort" size="small" maxlength='40'
                                        v-model.number="ipForm.TargetSnmpScanV2.Port"></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row :gutter="24">
                            <el-col :sm="24" :md="24" :lg="24" v-if="ipForm.TargetType === 3">
                                <el-form-item label="团体名" prop="TargetSnmpScanV2.GroupName">
                                    <el-input size="small" maxlength='40'
                                        v-model="ipForm.TargetSnmpScanV2.GroupName"></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row :gutter="24">
                            <el-col :sm="24" :md="24" :lg="24" v-if="ipForm.TargetType === 4">
                                <el-form-item label="交换机地址：" prop="TargetSnmpScanV3.ServerIP">
                                    <el-input oninput="value=value.replace(/[^0-9.]/g,'')" size="small" maxlength='40'
                                        v-model="ipForm.TargetSnmpScanV3.ServerIP"></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row :gutter="24">
                            <el-col :sm="24" :md="24" :lg="24" v-if="ipForm.TargetType === 4">
                                <el-form-item label="交换机snmp端口：" prop="TargetSnmpScanV3.Port">
                                    <el-input @input="validatePort" size="small" maxlength='40'
                                        v-model.number="ipForm.TargetSnmpScanV3.Port"></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row :gutter="24">
                            <el-col :sm="24" :md="24" :lg="24" v-if="ipForm.TargetType === 4">
                                <el-form-item label="团体名" prop="TargetSnmpScanV3.GroupName">
                                    <el-input size="small" maxlength='40'
                                        v-model="ipForm.TargetSnmpScanV3.GroupName"></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row :gutter="24" v-if="ipForm.TargetType === 4">
                            <el-col :sm="24" :md="24" :lg="24">
                                <el-form-item label="安全级别：" prop="SecurityLevel">
                                    <el-select v-model="ipForm.TargetSnmpScanV3.SecurityLevel" style="width:100%">
                                        <el-option label="不认证也不加密" :value="0"></el-option>
                                        <el-option label="认证但是不加密" :value="1"></el-option>
                                        <el-option label="既认证又加密" :value="2"></el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row :gutter="24" v-if="ipForm.TargetType === 4">
                            <el-col :sm="24" :md="24" :lg="24"
                                v-if="ipForm.TargetSnmpScanV3.SecurityLevel === 1 || ipForm.TargetSnmpScanV3.SecurityLevel === 2">
                                <el-form-item label="认证算法：" prop="TargetSnmpScanV3.AuthMD5OrSHA">
                                    <el-select v-model="ipForm.TargetSnmpScanV3.AuthMD5OrSHA" style="width:100%">
                                        <el-option label="MD5" value="MD5"></el-option>
                                        <el-option label="SHA" value="SHA"></el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row :gutter="24" v-if="ipForm.TargetType === 4">
                            <el-col :sm="24" :md="24" :lg="24"
                                v-if="ipForm.TargetSnmpScanV3.SecurityLevel === 1 || ipForm.TargetSnmpScanV3.SecurityLevel === 2">
                                <el-form-item label="认证密码：" prop="TargetSnmpScanV3.AuthPwd">
                                    <el-input size="small" maxlength='40'
                                        v-model="ipForm.TargetSnmpScanV3.AuthPwd"></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row :gutter="24" v-if="ipForm.TargetType === 4">
                            <el-col :sm="24" :md="24" :lg="24">
                                <el-form-item label="加密算法：" prop="TargetSnmpScanV3.AlgDESOrAES"
                                    v-if="ipForm.TargetSnmpScanV3.SecurityLevel === 2">
                                    <el-select v-model="ipForm.TargetSnmpScanV3.AlgDESOrAES" style="width:100%">
                                        <el-option label="DES" value="DES"></el-option>
                                        <el-option label="AES" value="AES"></el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row :gutter="24" v-if="ipForm.TargetType === 4">
                            <el-col :sm="24" :md="24" :lg="24">
                                <el-form-item label="加密密码：" prop="TargetSnmpScanV3.AlgPwd"
                                    v-if="ipForm.TargetSnmpScanV3.SecurityLevel === 2">
                                    <el-input size="small" maxlength='40'
                                        v-model="ipForm.TargetSnmpScanV3.AlgPwd"></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                    </el-form>
                    <span slot="footer" class="dialog-footer">
                        <el-button type="primary" @click="submit()">确 定</el-button>
                        <el-button type="info" @click="centerDialogVisible = false">取 消</el-button>
                    </span>
                </el-dialog>
                <el-table stripe highlight-current-row :data="tableData" :header-cell-style="{ 'text-align': 'center' }"
                    :cell-style="{ 'text-align': 'center' }" border height="calc(100vh - 200px)">
                    <el-table-column label="序号" width="80" type="index"
                        :index='(index) => { return (index + 1) + (pageNum - 1) * pageSize }'> </el-table-column>
                    <el-table-column prop="Name" label="任务名称" show-overflow-tooltip> </el-table-column>
                    <el-table-column prop="TargetType" label="扫描目标" show-overflow-tooltip>
                        <template slot-scope="{row}">
                            <span v-show="row.TargetType == 1">自定义</span>
                            <!-- <span v-show="row.TargetType == 2">指定IP组</span> -->
                            <span v-show="row.TargetType == 3">SNMP V1 / V2</span>
                            <span v-show="row.TargetType == 4">SNMP V3</span>
                        </template>
                    </el-table-column>
                    <el-table-column prop="ExecType" label="执行方式" show-overflow-tooltip :formatter="ExecTypeformatter">
                    </el-table-column>
                    <el-table-column prop="LastExecTime" label="扫描耗时" show-overflow-tooltip width="380px"
                        :formatter="LastTimeformatter"> </el-table-column>
                    <!-- <el-table-column prop="Port" label="下次扫描时间" show-overflow-tooltip> </el-table-column> -->
                    <!-- <el-table-column prop="Port" label="扫描结果" show-overflow-tooltip> </el-table-column> -->
                    <el-table-column prop="Port" label="状态" show-overflow-tooltip>
                        <template slot-scope="{row}">
                            <span v-if="row.LastExecResult === 0" style="color:#67C23A">成功</span>
                            <span v-if="row.LastExecResult === 1" style="color:#909399">执行中</span>
                            <span v-if="row.LastExecResult === 2" style="color:#F56C6C">失败</span>
                        </template>
                    </el-table-column>
                    <el-table-column label="操作" width="300">
                        <template slot-scope="scope">
                            <el-button type="primary" size="mini"
                                @click="scanning(scope.row, scope.$index)">再次扫描</el-button>
                            <el-button type="success" size="mini"
                                @click="addHost(2, scope.row, scope.$index)">修改</el-button>
                            <el-button type="success" size="mini" @click="details(scope.row)">详情</el-button>
                            <el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>
                        </template>
                    </el-table-column>
                    <template slot="empty">
                        <div class="empty">
                            <svg-icon icon-class="notAvailable" class="notAvailable"></svg-icon>
                            <!-- <span>{{imgTitle}}</span> -->
                        </div>
                    </template>
                </el-table>
                <el-dialog top="5vh" :close-on-click-modal="false" :close-on-press-escape=false title="资产详情"
                    :visible.sync="detailsDialog" v-el-drag-dialog width="600px">
                    <el-checkbox v-model="isNewDevice" style="margin-bottom: 10px;">仅显示新增发现资产</el-checkbox>
                    <span>总共扫描到 <span style="color: #67C23A">{{ allDevice }}</span> 个资产，新增资产 <span style="color: #F56C6C">{{
                        newDevice }}</span> 个</span>
                    <el-table stripe border :data="filteredDetails" style="width: 100%;" height="490px">
                        <el-table-column label="序号" width="60" type="index"> </el-table-column>
                        <el-table-column label="资产IP" prop="DeviceIP" show-overflow-tooltip></el-table-column>
                        <el-table-column label="资产MAC" prop="DeviceMAC" show-overflow-tooltip width="160"></el-table-column>
                        <el-table-column label="扫描结果" prop="Status" show-overflow-tooltip width="120">
                            <template slot-scope="{row}">
                                <span :style="{ color: row.Status === 1 ? '#67C23A' : '#F56C6C' }">{{ row.Status === 1 ?
                                    '存在资产' :
                                    '新增发现' }}</span>
                            </template>
                        </el-table-column>
                    </el-table>
                    <el-divider></el-divider>
                    <span slot="footer" class="dialog-footer">
                        <el-button type="info" @click="detailsDialog = false">关 闭</el-button>
                    </span>
                </el-dialog>
            </el-card>
        </div>
    </div>
</template>

<script>
import { toTree, parseTime, formatDuration2, validatePort } from '@/utils/index.js'
import { connrequest } from '@/api/firstPage';
import elDragDialog from '@/directive/el-drag-dialog' // base on element-ui
export default {
    directives: { elDragDialog },
    data() {
        var validators = (rule, value, callback) => {
            var regIP = /^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$/
            // var prefixIP = /^(?=(\b|\D))(((\d{1,2})|(1\d{1,2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{1,2})|(2[0-4]\d)|(25[0-5]))(?=(\b|\D))\/([1-2][0-9]|3[0-2]|[1-9])$/
            // var decimalnetmask = /^(?=(\b|\D))(((\d{1,2})|(1\d{1,2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{1,2})|(2[0-4]\d)|(25[0-5]))(?=(\b|\D))\/((254|252|248|240|224|192|128|0)\.0\.0\.0|(255\.(254|252|248|240|224|192|128|0)\.0\.0)|(255\.255\.(254|252|248|240|224|192|128|0)\.0)|(255\.255\.255\.(254|252|248|240|224|192|128|0)))$/;
            // var lasIP = /^(?=(\b|\D))(((\d{1,2})|(1\d{1,2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{1,2})|(2[0-4]\d)|(25[0-5]))(?=(\b|\D))-(?=(\b|\D))(((\d{1,2})|(1\d{1,2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{1,2})|(2[0-4]\d)|(25[0-5]))(?=(\b|\D))$/;
            if (regIP.test(value)) {
                callback()
            } else if (value === '' || value === undefined) {
                callback(new Error('地址不能为空'))
            } else {
                callback(new Error('请输入正确的IP地址格式'))
            }
        };
        return {
            centerDialogVisible: false,
            Action: 1,
            pageNum: 1,
            pageSize: 10,
            tableData: [],
            nodeData: [],
            detailsList: [],
            allDevice: 0,
            newDevice: 0,
            detailsDialog: false,
            isNewDevice: false,
            ipForm: {
                LoopScan: {
                    Interval: 1
                },
                TargetSnmpScanV2: {},
                TargetSnmpScanV3: {}
            },
            IPRule: {
                Name: { required: true, message: '不能为空', trigger: 'blur' },
                TargetIpSegment: { required: true, message: '不能为空', trigger: 'blur' },
                TargetDeviceGroupID: { required: true, message: '不能为空', trigger: 'change' },
                ExecType: [{ required: true, message: '不能为空', trigger: 'blur' }],
                TargetType: [{ required: true, message: '不能为空', trigger: 'blur' }],
                LoopScan: {
                    StartTime: [{ required: true, message: '不能为空', trigger: 'blur' }],
                    Interval: [{ required: true, message: '不能为空', trigger: 'blur' }],
                },
                TargetSnmpScanV2: {
                    ServerIP: [{ required: true, validator: validators, trigger: 'blur' },],
                    Port: [{ required: true, message: '不能为空', trigger: 'blur' }],
                    GroupName: [{ required: true, message: '不能为空', trigger: 'blur' }],
                },
                TargetSnmpScanV3: {
                    ServerIP: [{ required: true, validator: validators, trigger: 'blur' }],
                    Port: [{ required: true, message: '不能为空', trigger: 'blur' }],
                    GroupName: [{ required: true, message: '不能为空', trigger: 'blur' }],
                    SecurityLevel: [{ required: true, message: '不能为空', trigger: 'blur' }],
                    AuthMD5OrSHA: [{ required: true, message: '不能为空', trigger: 'blur' }],
                    AuthPwd: [{ required: true, message: '不能为空', trigger: 'blur' }],
                    AlgDESOrAES: [{ required: true, message: '不能为空', trigger: 'blur' }],
                    AlgPwd: [{ required: true, message: '不能为空', trigger: 'blur' }],
                }
            }
        }
    },
    computed: {
        // 筛选后的数据
        filteredDetails() {
            if (this.isNewDevice) {
                // 只显示 Status === 0 的对象
                return this.detailsList.filter(item => item.Status === 0);
            }
            // 显示全部数据
            return this.detailsList;
        }
    },
    created() {
        this.getData()
    },
    methods: {
        validatePort(value) {
            if (this.ipForm.TargetType === 3) {
                this.$set(this.ipForm.TargetSnmpScanV2, 'Port', validatePort(value))
            } else if (this.ipForm.TargetType === 4) {
                this.$set(this.ipForm.TargetSnmpScanV3, 'Port', validatePort(value))
            }
        },
        async getData() {
            const res = await connrequest('GetDeviceScanTask')
            this.tableData = res.Data
        },
        async scanning(row) {
            const paramData = {
                Data: {
                    Action: 2,
                    Detail: {
                        ...row,
                        LastExecTime: 0
                    }
                },
            }
            const res = await connrequest('EditDeviceScanTask', paramData);
            if (res.Status.StatusCode === 0) {
                this.$message.success('开启再次扫描成功，系统会再次启动扫描，请等待片刻后刷新查看');
                this.getData()
            }
        },
        // 执行方式格式转换
        ExecTypeformatter(row) {
            return row.ExecType === 1 ? '立即执行' : '定期执行'
        },
        // 最近扫描时间格式转换
        LastTimeformatter(row) {
            return row.ExecEndTime ? `${row.LastExecResult === 1 ? '' : formatDuration2(row.ExecEndTime - row.ExecStartTime)} ${parseTime(row.ExecStartTime)} - ${row.LastExecResult === 1 ? '-' : parseTime(row.ExecEndTime)}` : '-'
        },
        async snmpChange(row) {
            if (row === 2) {
                const res = await connrequest('GetDeviceGroup')
                this.nodeData = toTree(res.Data)
            }
            if (row === 4) {
                this.$set(this.ipForm.TargetSnmpScanV3, 'SecurityLevel', 0)
            }
        },
        async addHost(Status, row, index) {
            this.Action = Status
            this.centerDialogVisible = true
            if (Status == 2) {
                if (row.TargetType === 2) {
                    const res = await connrequest('GetDeviceGroup')
                    this.nodeData = toTree(res.Data)
                }
                this.ipForm = {
                    ...row,
                    TargetIpSegment: row.TargetIpSegment ? row.TargetIpSegment.join('\n') : '',
                    LoopScan: {
                        StartTime: row.LoopScan.StartTime * 1000,
                        Interval: row.LoopScan.Interval / 60 / 60
                    }
                }
            } else {
                this.ipForm = {
                    ExecType: 1,
                    TargetType: 1,
                    QuickScan: 0,
                    LoopScan: {
                        StartTime: new Date(),
                        Interval: 1
                    },
                    TargetSnmpScanV2: {},
                    TargetSnmpScanV3: {}
                }
            }
        },
        details(row) {
            this.detailsList = row.Device
            this.allDevice = this.detailsList.length
            this.newDevice = this.detailsList.filter(item => item.Status === 0).length
            this.detailsDialog = true
        },
        handleDelete(row) {
            this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(async () => {
                const paramData = {
                    Data: {
                        Action: 3,
                        Detail: {
                            ...row,
                        }
                    },
                }
                const res = await connrequest('EditDeviceScanTask', paramData);
                if (res.Status.StatusCode === 0) {
                    this.getData();
                    this.$message({
                        type: 'success',
                        message: '删除成功!'
                    });
                }
            }).catch(() => {
                this.$message({
                    type: 'info',
                    message: '已取消删除'
                });
            });
        },
        closeDialog() {
            // 重置表单
            this.$nextTick(() => {
                this.$refs['ipForm'].resetFields();
            });
        },
        submit() {
            this.$refs['ipForm'].validate(async (valid) => {
                if (valid) {
                    if (this.ipForm.TargetType === 1 && this.ipForm.TargetIpSegment) {
                        let allMatch = this.checkIPFormat(this.ipForm.TargetIpSegment)
                        if (!allMatch) {
                            this.$message.error('扫描目标有错误，请输入IP/IP段/IP范围，一行一个')
                            return false
                        }
                    }
                    const paramData = {
                        Data: {
                            Action: this.Action,
                            Detail: {
                                ...this.ipForm,
                                ID: this.Action == 1 ? Math.floor(Date.now() / 1000) : this.ipForm.ID,
                                LoopScan: {
                                    StartTime: Math.floor(this.ipForm.LoopScan.StartTime / 1000),
                                    Interval: this.ipForm.LoopScan.Interval * 60 * 60
                                },
                                TargetIpSegment: this.ipForm.TargetIpSegment ? this.ipForm.TargetIpSegment.split('\n') : ''
                            }
                        },
                    }
                    const res = await connrequest('EditDeviceScanTask', paramData);
                    if (res.Status.StatusCode === 0) {
                        this.$message.success(this.Action == 1 ? '添加成功' : '修改成功');
                        this.getData()
                        this.centerDialogVisible = false
                    }
                }
            })
        },
        checkIPFormat(str) {
            // 按换行分割输入字符串，并过滤空行
            const arr = str.split('\n').filter(item => item.trim() !== '');
            let allMatch = true;
            arr.forEach(item => {
                // 完整 IP 范围：192.168.1.1-192.168.1.2
                // const ipRangeRegex = /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})-(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/;
                // 网段：192.168.1-192.168.2
                // const ipSegmentRegex = /^(\d{1,3}\.\d{1,3}\.\d{1,3})-(\d{1,3}\.\d{1,3}\.\d{1,3})$/;
                // CIDR：192.168.1.1/24
                const ipCidrRegex = /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2})$/;
                // 单个 IP：192.168.1.1
                const ipRegex = /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/;
                // 新增：IP 最后一段范围，如 192.168.20.100-150
                const ipLastSegmentRangeRegex = /^(\d{1,3}\.\d{1,3}\.\d{1,3})\.(\d{1,3})-(\d{1,3})$/;
                if (
                    // ipRangeRegex.test(item) ||
                    // ipSegmentRegex.test(item) ||
                    ipCidrRegex.test(item) ||
                    ipRegex.test(item) ||
                    ipLastSegmentRangeRegex.test(item)
                ) {
                    // 匹配任一格式，保持 allMatch 不变
                } else {
                    allMatch = false;
                }
            });
            return allMatch;
        }
    }
}
</script>

<style lang='scss' scoped>
.btn-bottom {
    margin-bottom: 20px;
}

.box {
    border: none;
    transition: width 0.5s;
    /* 添加过渡动画 */
}

// .searchbutton {
//     border-bottom: 20px solid #293749;    
// }
// 表格底部边框

.el-tag--info {
    background-color: #f4f4f5 !important;
    border-color: #e9e9eb !important;
    color: #909399 !important;
}

.result {
    display: flex;

}

.el-form-item {
    margin-bottom: 15px !important;
}

.el-checkbox {
    margin-right: 15px !important;
}

// .el-select{
//     width: 40% !important;
// }
.flex-box {
    display: flex;
    align-items: center;
}

::v-deep .el-tree-node__content :hover {
    color: #c0c4ac !important;
}

::v-deep .el-tree-node__content>.custom-tree-node__content {
    color: #c0c4ac !important;
}

::v-deep .el-card__header {
    padding: 10px !important;
}

::v-deep .transfer-title {
    margin: 0 !important;
}

// .el-select{
//     // width: 74% !important;
// }
.el-form-item {
    margin-bottom: 17px !important;
}

::v-deep .el-dialog__body {
    max-height: 70vh !important;
    overflow: auto !important;
}

::v-deep.tree-line .el-tree-node {
    // height: 600px;
    background: #1b2532;
    color: white;
}

::v-deep.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content {
    color: white;
    background: linear-gradient(90deg, #09473D 15.83%, #1B2532 85.83%);
}

::v-deep.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content:hover {
    color: white;
    background: linear-gradient(90deg, #09473D 15.83%, #1B2532 85.83%);
}

::v-deep .el-tree__empty-block {
    background: #1b2532;
}

// 密码填充的时候
::v-deep input:-webkit-autofill,
textarea:-webkit-autofill,
select:-webkit-autofill {
    -webkit-text-fill-color: #ededed !important; //这个地方的颜色是字体颜色，可以根据实际情况修改
    -webkit-box-shadow: 0 0 0px 1000px #314054 inset !important; //设置input输入框的背景颜色为透明色
    background-color: transparent; //设置input输入框的背景颜色为透明色
    background-image: none;
    transition: background-color 50000s ease-in-out 0s;
    border: 1px solid #314054;
    border-radius: 2px;
}
</style>
